stylecontext: Listen to the new changed signal
authorBenjamin Otte <otte@redhat.com>
Sun, 8 Apr 2012 15:34:17 +0000 (17:34 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 17 Apr 2012 06:59:21 +0000 (08:59 +0200)
gtk/gtkcsstypes.c
gtk/gtkcsstypesprivate.h
gtk/gtkstylecontext.c

index e3519a0173aeac88babe888a71308aca211d43b3..f83880afab7964215ee7f117d8897350f4a33d2b 100644 (file)
@@ -56,6 +56,7 @@ _gtk_css_change_for_sibling (GtkCssChange match)
     { GTK_CSS_CHANGE_NAME, GTK_CSS_CHANGE_SIBLING_NAME },
     { GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_SIBLING_POSITION },
     { GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_SIBLING_STATE },
+    { GTK_CSS_CHANGE_SOURCE, 0 }
   };
 
   return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); 
@@ -72,7 +73,8 @@ _gtk_css_change_for_child (GtkCssChange match)
     { GTK_CSS_CHANGE_SIBLING_CLASS, GTK_CSS_CHANGE_PARENT_SIBLING_CLASS },
     { GTK_CSS_CHANGE_SIBLING_NAME, GTK_CSS_CHANGE_PARENT_SIBLING_NAME },
     { GTK_CSS_CHANGE_SIBLING_POSITION, GTK_CSS_CHANGE_PARENT_SIBLING_POSITION },
-    { GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE }
+    { GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE },
+    { GTK_CSS_CHANGE_SOURCE, 0 },
   };
 
   return gtk_css_change_translate (match, table, G_N_ELEMENTS (table)); 
index 22c1546d4efb4a63cb36a9ae941f30633de6c774..8890a5cce90aa10555e052e6f5a838c4a3e6f52d 100644 (file)
@@ -43,9 +43,10 @@ typedef enum { /*< skip >*/
   GTK_CSS_CHANGE_PARENT_SIBLING_POSITION  = (1 << 14),
   GTK_CSS_CHANGE_PARENT_SIBLING_STATE     = (1 << 15),
   /* add more */
+  GTK_CSS_CHANGE_SOURCE                   = (1 << 16)
 } GtkCssChange;
 
-#define GTK_CSS_CHANGE_ANY ((1 << 16) - 1)
+#define GTK_CSS_CHANGE_ANY ((1 << 17) - 1)
 #define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
 #define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
                                     GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
index 2d8023c298e701d215f1037800d524bfcbfbf059..de37c065951491b0934c408981e3322b924631d6 100644 (file)
 
 /* When these change we do a full restyling. Otherwise we try to figure out
  * if we need to change things. */
-#define GTK_STYLE_CONTEXT_RADICAL_CHANGE (GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS)
+#define GTK_STYLE_CONTEXT_RADICAL_CHANGE (GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_SOURCE)
 /* When these change we don't clear the cache. This takes more memory but makes
  * things go faster. */
 #define GTK_STYLE_CONTEXT_CACHED_CHANGE (GTK_CSS_CHANGE_STATE)
@@ -600,6 +600,52 @@ style_data_free (StyleData *data)
   g_slice_free (StyleData, data);
 }
 
+static void
+gtk_style_context_cascade_changed (GtkStyleCascade *cascade,
+                                   GtkStyleContext *context)
+{
+  GtkStyleContextPrivate *priv = context->priv;
+
+  if (priv->widget)
+    _gtk_style_context_queue_invalidate (context, GTK_CSS_CHANGE_SOURCE);
+  else
+    gtk_style_context_invalidate (context);
+}
+
+static void
+gtk_style_context_set_cascade (GtkStyleContext *context,
+                               GtkStyleCascade *cascade)
+{
+  GtkStyleContextPrivate *priv;
+
+  priv = context->priv;
+
+  if (priv->cascade == cascade)
+    return;
+
+  if (cascade)
+    {
+      g_object_ref (cascade);
+      g_signal_connect (cascade,
+                        "-gtk-private-changed",
+                        G_CALLBACK (gtk_style_context_cascade_changed),
+                        context);
+    }
+
+  if (priv->cascade)
+    {
+      g_signal_handlers_disconnect_by_func (priv->cascade, 
+                                            gtk_style_context_cascade_changed,
+                                            context);
+      g_object_unref (priv->cascade);
+    }
+
+  priv->cascade = cascade;
+
+  if (cascade)
+    gtk_style_context_cascade_changed (cascade, context);
+}
+
 static void
 gtk_style_context_init (GtkStyleContext *style_context)
 {
@@ -618,13 +664,14 @@ gtk_style_context_init (GtkStyleContext *style_context)
   priv->direction = GTK_TEXT_DIR_LTR;
 
   priv->screen = gdk_screen_get_default ();
-  priv->cascade = _gtk_style_cascade_get_for_screen (priv->screen);
-  g_object_ref (priv->cascade);
   priv->relevant_changes = GTK_CSS_CHANGE_ANY;
 
   /* Create default info store */
   info = style_info_new ();
   priv->info_stack = g_slist_prepend (priv->info_stack, info);
+
+  gtk_style_context_set_cascade (style_context,
+                                 _gtk_style_cascade_get_for_screen (priv->screen));
 }
 
 static void
@@ -641,13 +688,13 @@ gtk_style_context_finalize (GObject *object)
 
   gtk_style_context_set_parent (style_context, NULL);
 
+  gtk_style_context_set_cascade (style_context, NULL);
+
   if (priv->widget_path)
     gtk_widget_path_free (priv->widget_path);
 
   g_hash_table_destroy (priv->style_data);
 
-  g_object_unref (priv->cascade);
-
   g_slist_free_full (priv->info_stack, (GDestroyNotify) style_info_free);
 
   G_OBJECT_CLASS (gtk_style_context_parent_class)->finalize (object);
@@ -931,13 +978,14 @@ gtk_style_context_add_provider (GtkStyleContext  *context,
       
       new_cascade = _gtk_style_cascade_new ();
       _gtk_style_cascade_set_parent (new_cascade, priv->cascade);
-      g_object_unref (priv->cascade);
-      priv->cascade = new_cascade;
+      _gtk_style_cascade_add_provider (new_cascade, provider, priority);
+      gtk_style_context_set_cascade (context, new_cascade);
+      g_object_unref (new_cascade);
+    }
+  else
+    {
+      _gtk_style_cascade_add_provider (priv->cascade, provider, priority);
     }
-
-  _gtk_style_cascade_add_provider (priv->cascade, provider, priority);
-
-  gtk_style_context_invalidate (context);
 }
 
 /**
@@ -2369,9 +2417,7 @@ gtk_style_context_set_screen (GtkStyleContext *context,
 
   if (priv->cascade == _gtk_style_cascade_get_for_screen (priv->screen))
     {
-      g_object_unref (priv->cascade);
-      priv->cascade = _gtk_style_cascade_get_for_screen (screen);
-      g_object_ref (priv->cascade);
+      gtk_style_context_set_cascade (context, _gtk_style_cascade_get_for_screen (screen));
     }
   else
     {